home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 June / CHIP Haziran 2001.iso / prog / haziran / 19 / setup.exe / data.z / kptest.c < prev    next >
C/C++ Source or Header  |  2001-04-11  |  5KB  |  134 lines

  1. #include "../../../include/kpstdlib.h"
  2. #include "../../../include/wd_kp.h"
  3. #include "../kptest_com.h"
  4.  
  5.  
  6. BOOL __cdecl KP_Open(KP_OPEN_CALL *kpOpenCall, HANDLE hWD, PVOID pOpenData, PVOID *ppDrvContext);
  7. void __cdecl KP_Close(PVOID pDrvContext);
  8. void __cdecl KP_Call(PVOID pDrvContext, WD_KERNEL_PLUGIN_CALL *kpCall, BOOL fIsKernelMode);
  9. BOOL __cdecl KP_IntEnable(PVOID pDrvContext, WD_KERNEL_PLUGIN_CALL *kpCall, PVOID *ppIntContext);
  10. void __cdecl KP_IntDisable(PVOID pIntContext);
  11. BOOL __cdecl KP_IntAtIrql(PVOID pIntContext, BOOL *fIsMyInterrupt);
  12. DWORD __cdecl KP_IntAtDpc(PVOID pIntContext, DWORD dwCount);
  13.  
  14. BOOL __cdecl KP_Init(KP_INIT *kpInit)
  15. {
  16.     // check if the version of WD_KP.LIB is the same version as WINDRVR.H and WD_KP.H
  17.     if (kpInit->dwVerWD!=WD_VER)
  18.     {
  19.         // you need to re-compile your kernel plugin with the compatible version of WD_KP.LIB, WINDRVR.H and WD_KP.H!
  20.         return FALSE;
  21.     }
  22.  
  23.     kpInit->funcOpen = KP_Open;
  24.     strcpy (kpInit->cDriverName, "KPTEST"); // until 8 chars
  25.  
  26.     return TRUE;
  27. }
  28.  
  29. // called when WD_KernelPlugInOpen() is called. pDrvContext returned will be passed to 
  30. // rest of the functions
  31. BOOL __cdecl KP_Open(KP_OPEN_CALL *kpOpenCall, HANDLE hWD, PVOID pOpenData, PVOID *ppDrvContext)
  32. {
  33.     kpOpenCall->funcClose = KP_Close;
  34.     kpOpenCall->funcCall = KP_Call;
  35.     kpOpenCall->funcIntEnable = KP_IntEnable;
  36.     kpOpenCall->funcIntDisable = KP_IntDisable;
  37.     kpOpenCall->funcIntAtIrql = KP_IntAtIrql;
  38.     kpOpenCall->funcIntAtDpc = KP_IntAtDpc;
  39.     
  40.     *ppDrvContext = NULL; // you can allocate memory here
  41.  
  42.     return TRUE;
  43. }
  44.  
  45. // called when WD_KernelPlugInClose() is called
  46. void __cdecl KP_Close(PVOID pDrvContext)
  47. {
  48.     // you can free the memory allocated to pDrvContext here
  49. }
  50.  
  51. // called when WD_KernelPlugInCall() is called
  52. void __cdecl KP_Call(PVOID pDrvContext, WD_KERNEL_PLUGIN_CALL *kpCall, BOOL fIsKernelMode)
  53. {
  54.     kpCall->dwResult = KPTEST_OK;
  55.  
  56.     switch ( kpCall->dwMessage )
  57.     {
  58.     case KPTEST_MSG_VERSION: // in this sample we implement a GetVersion message
  59.         { 
  60.             DWORD dwVer = 100;
  61.             KPTEST_VERSION *ver = (KPTEST_VERSION *) kpCall->pData;
  62.             COPY_TO_USER_OR_KERNEL(&ver->dwVer, &dwVer, sizeof(DWORD), fIsKernelMode);
  63.             COPY_TO_USER_OR_KERNEL(ver->cVer, "My Driver V1.00", sizeof("My Driver V1.00")+1, fIsKernelMode);
  64.             kpCall->dwResult = KPTEST_OK;
  65.         }
  66.         break ;
  67.         // you can implement other messages here
  68.     default:
  69.         kpCall->dwResult = KPTEST_NO_IMPL_MESSAGE;
  70.     }
  71. }
  72.  
  73. // called when WD_IntEnable() is called, with a kernel plugin handler specified
  74. // the pIntContext will be passed to the rest of the functions handling interrupts.
  75. // returns TRUE if enable is succesful
  76. BOOL __cdecl KP_IntEnable(PVOID pDrvContext, WD_KERNEL_PLUGIN_CALL *kpCall, PVOID *ppIntContext)
  77. {
  78.     DWORD *pIntCount;
  79.  
  80.     // you can allocate memory specific for each interrupt in *ppIntContext
  81.     *ppIntContext = malloc(sizeof (DWORD)); 
  82.     if (!*ppIntContext)
  83.         return FALSE;
  84.     // in this sample the information is a DWORD used to count the incomming interrupts
  85.     pIntCount = (DWORD *) *ppIntContext;
  86.     *pIntCount = 0; // reset the count to zero
  87.  
  88.     return TRUE;
  89. }
  90.  
  91. // called when WD_IntDisable() is called
  92. void __cdecl KP_IntDisable(PVOID pIntContext)
  93. {
  94.     // you can free the interrupt specific memory to pIntContext here
  95.     free(pIntContext); 
  96. }
  97.  
  98. // returns TRUE if needs DPC.
  99. // this function is called at IRQL level - at physical interrupt handler.
  100. // most library calls are NOT allowed, for example:
  101. // NO   WD_xxxx() calls, except WD_Transfer(), 
  102. // NO   malloc, 
  103. // NO   free
  104. // YES  WD_Transfer
  105. // YES  your functions, as long as they dont call library functions
  106. // YES  specific kernel functions, that the Win DDK specifically allows them to be
  107. //      called at IRQL 
  108. BOOL __cdecl KP_IntAtIrql(PVOID pIntContext, BOOL *pfIsMyInterrupt)
  109. {
  110.     DWORD *pdwIntCount = (DWORD *) pIntContext;
  111.  
  112.     // you should check your hardware here to see if the interrupt belongs to you.
  113.     // if in doubt, return FALSE (this is the safest)
  114.     *pfIsMyInterrupt = FALSE;
  115.  
  116.     // in this example we will schedule a DPC once in every 5 interrupts
  117.     (*pdwIntCount) ++;
  118.     if (*pdwIntCount==5)
  119.     {
  120.         *pdwIntCount = 0;
  121.         return TRUE;
  122.     }
  123.  
  124.     return FALSE;
  125. }
  126.  
  127. // returns the number of times to notify user-mode (i.e. return from WD_IntWait)
  128. DWORD __cdecl KP_IntAtDpc(PVOID pIntContext, DWORD dwCount)
  129. {
  130.     return dwCount; // return WD_IntWait as many times as KP_IntAtIrql scheduled KP_IntAtDpc()
  131. }
  132.  
  133.  
  134.